﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using LizzabethBrownRealEstate.Models;
using System.Security.Permissions;
using System.Web.Security;

namespace LizzabethBrownRealEstate.Controllers
{
    public class UsersController : Controller
    {
        LBRDataContext dc = new LBRDataContext();

        public ActionResult Index()
        {
            // Add action logic here
            return View();
        }
       
        public ActionResult Authenticate()
        {
            string username = Request.Form["Username"];
            string password = Request.Form["Password"];
            bool rememberMe = false;
            if (this.IsValidLoginArgument(username, password))
            {
                if (Membership.ValidateUser(username, password))
                {
                    if (Request.Form["RememberMe"] == "on")
                    {
                        rememberMe = true;
                    }
                    
                    SetCookie(username, rememberMe);
                }
                else
                    this.ViewData["LoginFailed"] = "Login failed. Make sure you have entered a correct user name and password. Contact the webmaster if you need assistance.";
            }

            return RedirectToAction("Index", "Home");
        }

        internal ActionResult Authenticate(string username, string password)
        {
            bool rememberMe = false;
            if (this.IsValidLoginArgument(username, password))
            {
                if (Membership.ValidateUser(username, password))
                    SetCookie(username, rememberMe);
                else
                    this.ViewData["LoginFailed"] = "Login failed. Make sure you have entered a correct user name and password. Contact the webmaster if you need assistance.";
            }

            return RedirectToAction("Index", "Home");
        }

        public ActionResult LogOut()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }

        public ActionResult RegisterInfo()
        {
            ViewData.Add("UserName", "");
            ViewData.Add("First", "");
            ViewData.Add("Last", "");
            ViewData.Add("Email", "");
            ViewData.Add("Phone", "");
            ViewData.Add("Question", "");
            ViewData.Add("Answer", "");
            return RedirectToAction("Register");
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult EditMyProfile(string id)
        {
            User user = dc.Users.SingleOrDefault<User>(u => u.UserId.ToString() == id && u.Deleted == false);
            SiteMapNode n = new SiteMapNode(SiteMap.Provider, "tmp");
            return View(user);
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult MessageBoard(int categoryId)
        {

            ViewData.Add("CategoryId", categoryId);
            return View();
        }

        //[PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        //public ActionResult FilterMessageBoard(int categoryId)
        //{
        //    ViewData.Add("CategoryId", categoryId);
        //    return RedirectToAction("MessageBoard");
        //}

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult ViewTopic(int topicId)
        {
            ViewData.Add("TopicId", topicId);
            return View();
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult NewTopic()
        {
            return View();
        }
        
        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult NewMessage()
        {
            return View();
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult AddMessage()
        {
            Message m = new Message();
            m.Deleted = false;
            //m.ThreadId = Guid.NewGuid();
            User u = dc.GetUser(((Guid)Membership.GetUser().ProviderUserKey).ToString());
            m.User = u;
            m.CreateDate = System.DateTime.Now;
            Category c = dc.GetCategory(int.Parse(Request.Form["CategoryId"]));
            //m.Category = c;
            TryUpdateModel(m, Request.Form.AllKeys);
            dc.Messages.InsertOnSubmit(m);
            dc.SubmitChanges();

            ViewData.Add("CategoryId", Request.Form["CategoryId"]);
            return RedirectToAction("MessageBoard");
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult AddReply()
        {
            Message m = new Message();
            m.Deleted = false;
            
            User u = dc.GetUser(((Guid)Membership.GetUser().ProviderUserKey).ToString());
            m.User = u;
            m.CreateDate = System.DateTime.Now;
            //Category c = dc.GetCategory(int.Parse(Request.Form["CategoryId"]));
            //m.Category = c;
            TryUpdateModel(m, Request.Form.AllKeys);
            dc.Messages.InsertOnSubmit(m);
            dc.SubmitChanges();

            ViewData.Add("CategoryId", Request.Form["CategoryId"]);
            ViewData.Add("TopicId", Request.Form["TopicId"]);
            return RedirectToAction("ViewTopic", new {topicId=m.TopicId});
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult AddTopic()
        {
            Topic t = new Topic();
            t.Deleted = false;
            t.User = dc.GetUser(((Guid)Membership.GetUser().ProviderUserKey).ToString());
            t.Category = dc.GetCategory(int.Parse(Request.Form["CategoryId"]));
            TryUpdateModel(t, Request.Form.AllKeys);
            dc.Topics.InsertOnSubmit(t);

            Message m = new Message();
            m.User = t.User;
            m.HasBeenRead = false;
            TryUpdateModel(m, Request.Form.AllKeys);
            m.Topic = t;
            m.Deleted = false;
            dc.Messages.InsertOnSubmit(m);
            dc.SubmitChanges();
            
            ViewData.Add("TopicId", t.TopicId);
            return RedirectToAction("ViewTopic", new { topicId = m.TopicId });
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult Reply(int topicId)
        {
            Topic t = dc.GetTopic(topicId);
            return View(t);
        }

        public ActionResult Register()
        {
            User u = new User();
            
            try
            {
                LBRDataContext dc = new LBRDataContext();
                dc.Users.InsertOnSubmit(u);
                TryUpdateModel(u, Request.Form.AllKeys);
                string pswd = Request.Form["Password"];
                MembershipCreateStatus status = new MembershipCreateStatus();
                MembershipUser mu = Membership.CreateUser(u.UserName, pswd, u.Email, u.Question, u.Answer, true, out status);
                if (mu != null)
                {
                    Roles.AddUserToRole(u.UserName, Request.Form["Admin"] == null ? "Viewer" : "Administrator");
                    u.UserId = (Guid)mu.ProviderUserKey;
                    dc.SubmitChanges();
                    return Authenticate(u.UserName, Request.Form["Password"].ToString());
                }
                else
                {
                    ViewData.Add("UserName", Request.Form["UserName"]);
                    ViewData.Add("First", Request.Form["First"]);
                    ViewData.Add("Last", Request.Form["Last"]);
                    ViewData.Add("Email", Request.Form["Email"]);
                    ViewData.Add("Phone", Request.Form["Phone"]);
                    ViewData.Add("Question", Request.Form["Question"]);
                    ViewData.Add("Answer", Request.Form["Answer"]);
                    ViewData.Add("ResterError", GetRegistrationError(status));
                    return View();
                }
            }
            catch (Exception ex)
            {

            }
            return View();// u;
        }

        private string GetRegistrationError(MembershipCreateStatus status)
        {
            string s = "";
            switch (status)
            {
                case MembershipCreateStatus.DuplicateEmail: { s = "This email has already been entered."; break; }
                case MembershipCreateStatus.DuplicateUserName: { s = "This user name is already in use."; break; }
                case MembershipCreateStatus.InvalidAnswer: { s = "The secret answer supplied is not valid."; break; }
                case MembershipCreateStatus.InvalidEmail: { s = "The email entered is not valid."; break; }
                case MembershipCreateStatus.InvalidPassword: { s = "The password entered is not valid."; break; }
                case MembershipCreateStatus.InvalidQuestion: { s = "The secret question supplied is not valid."; break; }
                case MembershipCreateStatus.InvalidUserName: { s = "The user name entered is not valid."; break; }
                case MembershipCreateStatus.ProviderError: { s = "An unspecified error has occured. If the problem persists, please try again later."; break; }
                case MembershipCreateStatus.UserRejected: { s = "An unspecified error has occured. If the problem persists, please try again later."; break; }
                case MembershipCreateStatus.Success: { s = ""; break; }
            }
            return s;
        }

        private bool IsValidLoginArgument(string userName, string password)
        {
            return !(string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(password));
        }

        public ActionResult SetCookie(string username, bool persist)
        {
            FormsAuthentication.SetAuthCookie(username, true);
            HttpCookie cookie = FormsAuthentication.GetAuthCookie(username, true);
            if (cookie != null)
            {
                cookie.Value = DateTime.Now.ToString();
                if (persist)
                    cookie.Expires = DateTime.Now.AddDays(7);
            }

            return RedirectToAction("Index", "Home");
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult UpdateMyProfile(string id)
        {            
            User u = new User();
            if (!String.IsNullOrEmpty(Request.Form["UserName"]))
            {
                if (id != null)
                    u = dc.GetUser(id);

                TryUpdateModel(u, Request.Form.AllKeys);
                if (id == null)
                    dc.Users.InsertOnSubmit(u);

                dc.SubmitChanges();
            }
            return RedirectToAction("EditMyProfile", u);
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult PropertySearch()
        {
            RealEstateProperty p = new RealEstateProperty();
            return View(p);
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult DoPropertySearch()
        {
            RealEstateProperty rep = new RealEstateProperty();
            List<Location> locs = new List<Location>();
            if (Request.Form["LocationList"] != null)
            {
                foreach (String id in Request.Form["LocationList"].ToString().Split(','))
                {
                    locs.Add(dc.Locations.Where<Location>(l => l.LocationId == int.Parse(id)).SingleOrDefault<Location>());
                }
            }
            string price = Request.Form["PriceString"];
            int _price = 0;
            price = price.Replace(",", "");
            price = price.Replace(".", "");
            price = price.Replace("$", "");
            int.TryParse(price, out _price);
            rep.Price = _price;

            if (bool.Parse(Request.Form["Bsmnt"]))
                rep.Basement = true;

            if (bool.Parse(Request.Form["NewConst"]))
                rep.NewConstruction = true;

            if (bool.Parse(Request.Form["Hist"]))
                rep.Historic = true;

            if (bool.Parse(Request.Form["GargAttch"]))
                rep.GarageAttached = true; ;

            if (bool.Parse(Request.Form["Garg"]))
                rep.Garage = true;

            if (Request.Form["Baths"].Length > 0)
            {
                int baths = 0;
                int.TryParse(Request.Form["Baths"].ToString(), out baths);
                rep.Bathrooms = baths;
            }

            if (Request.Form["Firepl"].Length > 0)
            {
                int fp = 0;
                int.TryParse(Request.Form["Firepl"].ToString(), out fp);
                rep.Fireplaces = fp;
            }

            if (Request.Form["FBaths"].Length > 0)
            {
                int fb = 0;
                int.TryParse(Request.Form["FBaths"].ToString(), out fb);
                rep.FullBaths = fb;
            }

            if (Request.Form["Rms"].Length > 0)
            {
                int rms = 0;
                int.TryParse(Request.Form["Rms"].ToString(), out rms);
                rep.Rooms = rms;
            }

            if (Request.Form["TLA"].Length > 0)
            {
                int tla = 0;
                int.TryParse(Request.Form["TLA"].ToString(), out tla);
                rep.TotalLivingArea = tla;
            }

            if (Request.Form["BRms"].Length > 0)
            {
                int brms = 0;
                int.TryParse(Request.Form["BRms"].ToString(), out brms);
                rep.Bedrooms = brms;
            }

            if (Request.Form["Frnt"].Length > 0)
            {
                int frnt = 0;
                int.TryParse(Request.Form["Frnt"].ToString(), out frnt);
                rep.Frontage = frnt;
            }

            if (Request.Form["TSqFt"].Length > 0)
            {
                int tsqft = 0;
                int.TryParse(Request.Form["TSqFt"].ToString(), out tsqft);
                rep.TotalSquareFeet = tsqft;
            }

            if (Request.Form["MLSNum"].Length > 0)
            {
                rep.MLSNumber = Request.Form["MLSNum"].ToString();
            }

            //TryUpdateModel(rep, Request.Form.AllKeys);
            IEnumerable<RealEstateProperty> results = dc.PropertySearch(rep, locs);
            TempData.Add("PropertyList", results.AsEnumerable<RealEstateProperty>());
            return RedirectToAction("SearchResults", results.AsEnumerable<RealEstateProperty>());
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult SearchResults()
        {
            ViewData.Add("PropertyList", TempData["PropertyList"]);
            return View();
        }

        [PrincipalPermission(SecurityAction.Demand, Role = "Viewer")]
        public ActionResult ReadNewsItem(int newsItemId)
        {
            ViewData.Add("NewsItemId", newsItemId);
            return View();
        }

    }
}
